package com.t2t.top.devops.service.impl;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.hash.Hashing;
import com.t2t.top.base.exception.ServiceException;
import com.t2t.top.devops.constant.DevopsConstants;
import com.t2t.top.devops.dao.AccountMapper;
import com.t2t.top.devops.model.po.Account;
import com.t2t.top.devops.model.po.AccountExample;
import com.t2t.top.devops.model.po.Issue;
import com.t2t.top.devops.service.AccountService;
import com.t2t.top.devops.util.PasswordHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author yangpengfei
 */
@Service
@Transactional(rollbackFor = ServiceException.class)
class AccountServiceImpl implements AccountService {

    protected Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);

    @Resource
    private AccountMapper accountMapper;

    public void delete(String ids) throws ServiceException {
        String[] arr = ids.split(",");
        for (int i = 0; i < arr.length; i++) {
            Account po = (Account) accountMapper.selectByPrimaryKey(Integer.parseInt(arr[i]));
            accountMapper.deleteByPrimaryKey(po.getId());
        }
    }

    @Override
    public Account findById(Integer id) throws ServiceException {
        return accountMapper.selectByPrimaryKey(id);
    }

    @Override
    public void resetPswd(Integer id) throws ServiceException {
        Account account = new Account();
        account.setId(id);
        account.setPassword(DevopsConstants.DEFAULT_PASSWORD);
        PasswordHelper.encryptPassword(account);
        accountMapper.updateByPrimaryKeySelective(account);
    }

    @Override
    public void changePswd(String name, String oldPswd, String newPswd) throws ServiceException {
        Assert.notNull(name);
        Assert.notNull(oldPswd);
        Assert.notNull(newPswd);
        authe(name, oldPswd);
        Account account = findAccountByName(name);
        account.setPassword(newPswd);
        PasswordHelper.encryptPassword(account);
        accountMapper.updateByPrimaryKeySelective(account);
    }

    @Override
    public void authe(String name, String pswd) throws ServiceException {
        if (Strings.isNullOrEmpty(name) || Strings.isNullOrEmpty(pswd)) {
            throw new ServiceException("用户名或密码为空");
        }
        Account account = findAccountByName(name);
        if (account == null) {
            logger.error("用户不存在：" + name);
            throw new ServiceException("用户或密码错误");
        }
        if (account.getCanUse() == DevopsConstants.RECORD_STATUS_NO_CAN_USE) {
            logger.error("用户已经被禁用：" + name);
            throw new ServiceException("用户已经被禁用!");
        }
        String persistPswd = account.getPassword();
        String salt = account.getSalt();
        String mixMd5 = Hashing.md5().newHasher().putString(pswd + salt, Charsets.UTF_8).hash().toString().toLowerCase();
        boolean authe = persistPswd.equalsIgnoreCase(mixMd5);
        if (!authe) {
            logger.error("密码错误：" + name);
            throw new ServiceException("密码错误");
        }
    }

    @Override
    public void update(Account account) throws ServiceException {
        Assert.notNull(account);
        //add
        if (account.getId() == null) {
            account.setPassword("123456");//首次创建，密码默认123456
            addAccount(account);
            return;
        }
        //update
        updateAccount(account);
    }

    public List query(Account account) throws ServiceException {
        AccountExample e = new AccountExample();
        if (StringUtils.isNotEmpty(account.getName())) {
            e.createCriteria().andNameLike(account.getName());
        }
        return accountMapper.selectByExample(e);
    }

    public Account findAccountByName(String name) throws ServiceException {
        AccountExample e = new AccountExample();
        e.createCriteria().andNameEqualTo(name);
        List<Account> accounts = accountMapper.selectByExample(e);
        if (accounts.size() > 0) {
            return accounts.get(0);
        }
        return null;
    }

    private Account addAccount(Account account) throws ServiceException {
        Assert.notNull(account);
        String name = account.getName();
        String pswd = account.getPassword();
        if (Strings.isNullOrEmpty(name) || Strings.isNullOrEmpty(pswd)) {
            throw new ServiceException("用户名或密码为空");
        }
        Account persistAccount = findAccountByName(name);
        if (persistAccount != null) {
            throw new ServiceException("新增用户失败，用户名已存在：" + name);
        }
        //密码加密
        PasswordHelper.encryptPassword(account);
        account.setCanUse(DevopsConstants.RECORD_STATUS_CAN_USE);//default
        account.setCreateTime(new Date());
        try {
            accountMapper.insertSelective(account);
            return account;
        } catch (Exception e) {
            throw new ServiceException("新增用户失败", e);
        }
    }

    private void updateAccount(Account account) throws ServiceException {
        if (StringUtils.isEmpty(account.getName())) {
            throw new ServiceException("用户名不能为空串，id：" + account.getId());
        }

        Account pobyid = accountMapper.selectByPrimaryKey(account.getId());//该对象必定存在，故不需要判断
        Account pobyname = findAccountByName(account.getName());//该对象可能为null
        //如果根据用户名查询出来的对象和根据ID查处的对象非同一个，且用户名一样，说明改用户已存在
        if (pobyname != null && pobyname.getId() != pobyid.getId() && StringUtils.equals(account.getName(), pobyname.getName())) {
            throw new ServiceException("修改用户失败，用户名已存在：" + account.getName());
        }

        account.setId(account.getId());
        account.setPassword(null);//密码不可修改
        accountMapper.updateByPrimaryKeySelective(account);
    }

}
